//
//  ImageIOUtility.m
//  iOSStudy
//
//  Created by Evan Xie on 8/24/15.
//  Copyright (c) 2015 Family Wings. All rights reserved.
//

#import <ImageIO/ImageIO.h>
#import "ImageIOUtility.h"


@implementation ImageIOUtility

static CGImageSourceRef _CreateCGImageSourceFromFileURL(NSURL *imageURL)
{
    if (!imageURL) {
        AppLog(@"Invalid image URL");
        return nil;
    }
    
    CFDictionaryRef options = NULL;
    CFStringRef optionKeys[2];
    CFTypeRef optionsValues[2];
    
    optionKeys[0] = kCGImageSourceShouldCache;
    optionsValues[0] = (CFTypeRef)kCFBooleanTrue;
    optionKeys[1] = kCGImageSourceShouldAllowFloat;
    optionsValues[1] = (CFTypeRef)kCFBooleanTrue;
    
    options = CFDictionaryCreate(NULL, (const void **)optionKeys, (const void **)optionsValues, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CGImageSourceRef sourceRef = CGImageSourceCreateWithURL((__bridge CFURLRef)imageURL, options);
    CFRelease(options);
    
    if (!sourceRef) {
        AppLog(@"Failed to create CGImageSourceRef from %@", imageURL.absoluteString);
        return nil;
    }
    
    return sourceRef;
}

static UIImage *_CreateThumbnailFromImageSource(CGImageSourceRef imageSourceRef, NSInteger thumbnailSize)
{
    CFDictionaryRef options;
    CFStringRef optionKeys[3];
    CFTypeRef optionValues[3];
    CFNumberRef sizeNumberRef = CFNumberCreate(NULL, kCFNumberCGFloatType, &thumbnailSize);
    
    optionKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
    optionValues[0] = (CFTypeRef)kCFBooleanTrue;
    optionKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
    optionValues[1] = (CFTypeRef)kCFBooleanTrue;
    optionKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
    optionValues[2] = (CFTypeRef)sizeNumberRef;
    
    options = CFDictionaryCreate(NULL, (const void **)optionKeys, (const void **)optionValues, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CGImageRef thumbnailRef = CGImageSourceCreateThumbnailAtIndex(imageSourceRef, 0, options);
    CFRelease(options);
    CFRelease(sizeNumberRef);
    
    if (!thumbnailRef) {
        AppLog(@"Generate thumbnail CGImageRef failed.");
        return nil;
    }
    
    UIImage *thumbnail = [UIImage imageWithCGImage:thumbnailRef];
    CGImageRelease(thumbnailRef);
    
    return thumbnail;
}

+ (UIImage *)imageWithFileURL:(NSURL *)imageURL;
{
    CGImageSourceRef imageSourceRef = _CreateCGImageSourceFromFileURL(imageURL);
    CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSourceRef, 0, NULL);
    UIImage *image = [UIImage imageWithCGImage:imageRef];
    CFRelease(imageSourceRef);
    CGImageRelease(imageRef);
    
    return image;
}

+ (UIImage *)thumbnailWithImageURL:(NSURL *)imageURL size:(NSInteger)thumbnailSize
{
    CGImageSourceRef imageSourceRef = _CreateCGImageSourceFromFileURL(imageURL);
    UIImage *thumbnail = _CreateThumbnailFromImageSource(imageSourceRef, thumbnailSize);
    CFRelease(imageSourceRef);
    
    return thumbnail;
}

+ (NSDictionary *)imagePropertiesDictionaryWithImageURL:(NSURL *)imageURL
{
    if (!imageURL) {
        return nil;
    }
    
    NSMutableDictionary *propertiesDic = [NSMutableDictionary dictionaryWithCapacity:0];
    
    CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)imageURL, NULL);
    if (source) {
        CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
        if (imageProperties) {
            [propertiesDic addEntriesFromDictionary:(__bridge NSDictionary *)imageProperties];
            CFRelease(imageProperties);
        }
        
        CFRelease(source);
    }
    
    return propertiesDic;
}

@end
